from rest_framework import serializers #序列化器
from .models import User
from django_redis import get_redis_connection
import re    #正则
class UserSerializer(serializers.ModelSerializer):

    '''额外字段'''
    sms_code = serializers.CharField(max_length=6,min_length=4,write_only=True
                                     ,help_text="手机验证码",label="短信验证码")
    token = serializers.CharField(max_length=1000,read_only=True,label="jwt")

    class Meta:
        '''序列化器模型'''
        model = User
        fields = ["id","username","phone","password","nickname","sms_code","token"]
        extra_kwargs = {
            "nickname":{"required":True},
            "password":{"write_only":True,"max_length":16,"min_length":6},
            "phone":{"write_only":True},
            "username":{"read_only":True}
        }

    def validate(self, attrs):
        '''判断条件'''
        phone = attrs.get("phone")
        sms_code = attrs.get("sms_code")
        if not re.match("^1[3-9]\d{9}$",phone):
            raise serializers.ValidationError("手机号码格式不正确")

        redis_con = get_redis_connection("sms_code")
        sever_sms_code_bytes = redis_con.get("sms_%s"%phone)
        if sever_sms_code_bytes is None:
            raise serializers.ValidationError("验证码过期了")
        sever_sms_code = sever_sms_code_bytes.decode()
        if sever_sms_code_bytes != sever_sms_code:
            raise serializers.ValidationError("验证码错误")
        else:
            redis_con.delete("sms_%s"%phone)
        attrs.pop("sms_code")
        return attrs

    def create(self, validated_data):
        '''创建模型函数'''
        try:
            user = User.objects.create_user(
                username=validated_data.get("phone"),
                phone=validated_data.get("phone"),
                password=validated_data.get("password"),
            )
        except:
            raise serializers.ValidationError("注册失败")

        user.set_password(validated_data.get("password"))
        user.save()

        '''手动生成token'''
        from rest_framework_jwt.settings import api_settings

        jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
        jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

        payload = jwt_payload_handler(user)
        user.token = jwt_encode_handler(payload)

        return user